import { logUnderline, logTitle, logSubTitle, log } from "../utils/index";
function use() {
    logTitle("二、接口");
    logSubTitle("1、接口写法");
    logSubTitle("2、可选");
    logSubTitle("3、只读");
    logSubTitle("4、可索引类型");
    logSubTitle("5、描述函数的接口");

    interface Person {
        name: string;
        age: number;
        // ? 可选
        work?: string;
        // 只读，只能在初始时赋值
        readonly sex: string;
        // 【注释1】可索引类型，比如a[1], soure['name']，ts支持数字和字符串两种索引
        // 数字索引返回值 必须是 字符串索引返回值的 子类型！！！ 因为数字会自动转换成字符，二者需要保持一致【见最下方例1】
        // 此处，这般书写可以保证拓展性
        [anyKey: string]: any;
    }

    function isPersonWork(person: Person): boolean {
        return person.work !== "";
    }

    let person1: Person = {
        name: "lhf",
        age: 12,
        work: "clean",
        sex: "man",
        other: "1111",
    };
    // person1.sex = "woman"; // error

    // >>> 3. 只读数组，去掉了数组的所有可变方法
    let onlyReadArr: ReadonlyArray<number> = [1, 2, 3];
    // onlyReadArr.push(4) // error

    // >>> 3.1 调用
    // 当有 other: "1111" 时会报错，因为接口中没有规定该字段；或放开【注释1】；或使用断言；或赋值给另一个变量
    // **********************************
    isPersonWork(person1);
    // isPersonWork(person1 as Person) // 使用断言
    // let isWork = isPersonWork(person1)

    // >>> 4 函数接口
    interface checkWork {
        (person: Person): boolean;
    }
    // 重写上述方法，此时可以不写类型，编译器会自动根据接口来判断
    let isPersonWorkSimple: checkWork;
    isPersonWorkSimple = function (person) {
        return person.work !== "";
    };

    logSubTitle("6、类类型");
    // 类接口描述了公有部分，不能弄静态的
    interface IRun {
        aim: string;
        speed: string;
        run(aim: string, speed: string): void;
    }

    class Animal implements IRun {
        aim!: string;
        speed!: string;
        constructor(aim: string, speed: string) {
            this.run(aim, speed);
        }
        run(aim: string, speed: string): void {
            console.log(`动物朝着${aim}以${speed}的速度狂奔！！！`);
        }
    }

    let animal1 = new Animal("芝加哥", "30公里/小时");

    logSubTitle("7、类静态部分与实例部分的区别"); // 待填充
    logSubTitle("8、继承接口"); 
    logSubTitle("9、接口继承类"); // 待填充

    // 一个接口可以继承多个接口
    // interface IQuickRun extends IRun1, IRun2
    interface IQuickRun extends IRun {
        quick: boolean;
    }
    let quickRunObj = <IQuickRun>{};
    quickRunObj.quick = true;
    quickRunObj.speed = "12";

    
    logUnderline();

    // 例1
    interface Dict {
        // [index: number]: number;
        // 可以加入只读，这样就不能给索引赋值
        readonly [index: number]: number;
        length: number; // 这是可以的
        // name: string; // 报错。 number 不是 string 的子类型
    }

    let dict1: Dict = [1, 2, 3];
    // dict1[2] = 1; // error
}

export default { use };
